package com.ruicar.afs.cloud.afscase.mq.receiver.processor;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruicar.afs.cloud.afscase.approvetask.entity.CaseApproveRecord;
import com.ruicar.afs.cloud.afscase.cargpsmanage.entity.CarGpsApply;
import com.ruicar.afs.cloud.afscase.cargpsmanage.service.CarGpsApplyService;
import com.ruicar.afs.cloud.afscase.cargpsmanage.service.GpsManageService;
import com.ruicar.afs.cloud.afscase.infomanagement.entity.CaseContractInfo;
import com.ruicar.afs.cloud.afscase.infomanagement.service.CaseContractInfoService;
import com.ruicar.afs.cloud.afscase.loanactivatepool.entity.LoanActivatePool;
import com.ruicar.afs.cloud.afscase.loanactivatepool.service.LoanActivateService;
import com.ruicar.afs.cloud.afscase.loanapprove.condition.LoanApproveCondition;
import com.ruicar.afs.cloud.afscase.loanapprove.service.LoanApproveService;
import com.ruicar.afs.cloud.afscase.processor.enums.LoanSubmitEnum;
import com.ruicar.afs.cloud.common.core.enums.AfsEnumUtil;
import com.ruicar.afs.cloud.common.core.security.service.AfsUser;
import com.ruicar.afs.cloud.common.core.security.util.SecurityUtils;
import com.ruicar.afs.cloud.common.modules.afscorebusiness.enums.*;
import com.ruicar.afs.cloud.common.modules.contract.enums.ContractBusinessEnum;
import com.ruicar.afs.cloud.common.modules.dto.mq.loan.contractdto.LoanActivateReceiveNoticeDTO;
import com.ruicar.afs.cloud.common.modules.dto.mq.loan.gpsdto.ApplyGpsInfoDto;
import com.ruicar.afs.cloud.common.mq.rabbit.listener.AfsMqBizProcessor;
import com.ruicar.afs.cloud.common.mq.rabbit.message.MqTransCode;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;

import java.util.Date;

/**
 * @Description 合同激活通知
 * @Author yk.Li
 * @Date 2020/08/12
 */
@AllArgsConstructor
@Slf4j
@Component
@ConditionalOnProperty(prefix = "com.ruicar.afs.cloud.mq.rabbit",name="enable")
public class ContractActicateNoticeProcessor implements AfsMqBizProcessor<LoanActivateReceiveNoticeDTO> {

    private final LoanActivateService loanActivateService;
    private final CaseContractInfoService caseContractInfoService;
    private final LoanApproveService loanApproveService;


    @Override
    public boolean processMessage(LoanActivateReceiveNoticeDTO loanActivateReceiveNoticeDTO) throws Exception {
        try {
            log.info(">>>>>>>>>>接收合同激活通知 START>>>>>>>>>>>>", loanActivateReceiveNoticeDTO);
            this.dealContractNotice(loanActivateReceiveNoticeDTO);
            log.info(">>>>>>>>>>接收合同激活通知 END>>>>>>>>>>>>", loanActivateReceiveNoticeDTO);
        } catch (Exception e) {
            log.error("接收合同激活通知失败", loanActivateReceiveNoticeDTO, e.getMessage());
            return Boolean.FALSE;
        }
        return Boolean.TRUE;
    }

    @Override
    public MqTransCode getCode() {
        return MqTransCode.AFS_CONTRACT_BASIC_CASE_CTM_ACTIVATION_STATUS;
    }

    /**
     * @Description 解析GPS申请信息
     * @Author yk.Li
     * @Date 2020/08/10
     */
    public void dealContractNotice(LoanActivateReceiveNoticeDTO loanActivateReceiveNoticeDTO) {
        Assert.isTrue(null!=loanActivateReceiveNoticeDTO,"合同推送通知信息异常，接口参数不存在...");
        Assert.isTrue(null!=loanActivateReceiveNoticeDTO.getContractNo(),"合同系统推送合同号不存在...");
        log.info("收到合同系统回传数据：{}",JSONObject.toJSONString(loanActivateReceiveNoticeDTO));
        ContractBusinessEnum contractBusinessEnum = loanActivateReceiveNoticeDTO.getCaseType();
        switch (contractBusinessEnum){
            case activationSuccess:
                doActivationSuccess(loanActivateReceiveNoticeDTO);
                break;
            case activationFail:
                doActivationFail(loanActivateReceiveNoticeDTO);
                break;
            case cancelContract:
                doCancelContract(loanActivateReceiveNoticeDTO);
                break;
            case normalSettle:
                doNormalSettle(loanActivateReceiveNoticeDTO);
                break;
            case advanceSettle:
                doAdvanceSettle(loanActivateReceiveNoticeDTO);
                break;
            case closeContract:
                doCloseContract(loanActivateReceiveNoticeDTO);
                break;
            default:
                log.error(loanActivateReceiveNoticeDTO.getContractNo()+"收到合同系统推送数据，未找到相应命令："+contractBusinessEnum);
                break;
        }
    }
    public void doActivationSuccess(LoanActivateReceiveNoticeDTO dto){
        log.info(dto.getContractNo()+"======合同激活成功保存业务数据开始=======");
        LoanActivatePool pool=loanActivateService.getOne(Wrappers.<LoanActivatePool>lambdaQuery().eq(LoanActivatePool::getContractNo,dto.getContractNo()));
        CaseContractInfo caseContractInfo=caseContractInfoService.getOne(Wrappers.<CaseContractInfo>lambdaQuery().eq(CaseContractInfo::getContractNo,dto.getContractNo()));
        if(pool.getActStatus().equals(ActivateStatusEnum.UN_ACTIVATE.getStatus())){
            pool.setActStatus(ActivateStatusEnum.ACTIVATE.getStatus());
            pool.setActTime(dto.getCaseDate());
            /**避免数据异常重复发送激活任务，设置激活步骤为完成：100*/
            pool.setContractActiveSteps(100);
            pool.setContractActivateFlag(WhetherEnum.YES.getCode());//默认落库成功
            loanActivateService.updateById(pool);

            caseContractInfo.setStartDate(dto.getCaseDate());
            caseContractInfo.setEndDate(dto.getContractEndDate());
            caseContractInfo.setContractStatus(ContractStatusEnum.contractEffective);
            caseContractInfo.setLoanDate(dto.getCaseDate());
            caseContractInfoService.updateById(caseContractInfo);
            /**添加合作商展业城市首单记录*/
            loanApproveService.saveIsFirstMortgage(caseContractInfo.getContractNo());
            log.info(dto.getContractNo()+"======合同激活成功保存业务数据结束=======");
        }else {
            log.info(dto.getContractNo()+"合同状态为:{}，跳过修改",pool.getActStatus());
        }
    }

    public void doActivationFail(LoanActivateReceiveNoticeDTO dto){
        log.info(dto.getContractNo()+"======合同激活失败保存业务数据开始=======");
        LoanActivatePool pool=loanActivateService.getOne(Wrappers.<LoanActivatePool>lambdaQuery().eq(LoanActivatePool::getContractNo,dto.getContractNo()));
        if(pool.getActStatus().equals(ActivateStatusEnum.UN_ACTIVATE.getStatus())){
            pool.setContractActivateFlag(WhetherEnum.NO.getCode());
            /**回退激活步骤，以便再次执行激活方法*/
            pool.setContractActiveSteps(5);
            loanActivateService.updateById(pool);
            log.info(dto.getContractNo()+"======合同激活失败保存业务数据结束=======");
        }else {
            log.info(dto.getContractNo()+"合同状态为:{}，跳过修改",pool.getActStatus());
        }
    }
    public void doCancelContract(LoanActivateReceiveNoticeDTO dto){
        log.info(dto.getContractNo()+"======合同取消保存业务数据开始=======");
        CaseContractInfo caseContractInfo=caseContractInfoService.getOne(Wrappers.<CaseContractInfo>lambdaQuery().eq(CaseContractInfo::getContractNo,dto.getContractNo()));
        caseContractInfo.setContractStatus(ContractStatusEnum.flatCancel);
        caseContractInfo.setApplyStatus(ApplyStatusEnum.FLAT_CANCEL.getState());
        caseContractInfo.setUpdateTime(dto.getCaseDate());
        caseContractInfoService.updateById(caseContractInfo);
        //记录合同激活后取消日志
        CaseApproveRecord lockOprRecord = new CaseApproveRecord();
        lockOprRecord.setContractNo(caseContractInfo.getContractNo());
        lockOprRecord.setUseScene(UseSceneEnum.GENERAL_LOAN.getValue());
        lockOprRecord.setApproveSuggest(ApplyStatusEnum.LOAN_DISCARD.getState());
        lockOprRecord.setApproveSuggestName("合同取消");
        lockOprRecord.setApproveStartTime(new Date());
        lockOprRecord.setApproveEndTime(new Date());
        lockOprRecord.setApproveType(ApproveTypeEnum.CANAEL.getValue());
        lockOprRecord.setFlowNode(caseContractInfo.getFlowNode());
        log.info(dto.getContractNo()+"======合同取消保存业务数据结束=======");
    }
    public void doNormalSettle(LoanActivateReceiveNoticeDTO dto){
        log.info(dto.getContractNo()+"======合同正常结清保存业务数据开始=======");
        CaseContractInfo caseContractInfo=caseContractInfoService.getOne(Wrappers.<CaseContractInfo>lambdaQuery().eq(CaseContractInfo::getContractNo,dto.getContractNo()));
        if(caseContractInfo.getContractStatus().equals(ContractStatusEnum.contractEffective)) {
            caseContractInfo.setContractStatus(ContractStatusEnum.normalSettle);
            caseContractInfo.setSettleDate(dto.getCaseDate());
            caseContractInfo.setEndDate(dto.getCaseDate());
            caseContractInfo.setSettleType(AfsEnumUtil.key(ContractStatusEnum.normalSettle));
            caseContractInfoService.updateById(caseContractInfo);
            log.info(dto.getContractNo() + "======合同正常结清保存业务数据结束=======");
        }else{
            log.info(dto.getContractNo() + "合同状态为非生效状态：{}，跳过修改！",caseContractInfo.getContractStatus());
        }
    }
    public void doAdvanceSettle(LoanActivateReceiveNoticeDTO dto){
        log.info(dto.getContractNo()+"======合同提前结清保存业务数据开始=======");
        CaseContractInfo caseContractInfo=caseContractInfoService.getOne(Wrappers.<CaseContractInfo>lambdaQuery().eq(CaseContractInfo::getContractNo,dto.getContractNo()));
        if(caseContractInfo.getContractStatus().equals(ContractStatusEnum.contractEffective)) {
            caseContractInfo.setContractStatus(ContractStatusEnum.advanceSettle);
            caseContractInfo.setSettleDate(dto.getCaseDate());
            caseContractInfo.setEndDate(dto.getCaseDate());
            caseContractInfo.setSettleType(AfsEnumUtil.key(ContractStatusEnum.advanceSettle));
            caseContractInfoService.updateById(caseContractInfo);
            log.info(dto.getContractNo() + "======合同提前结清保存业务数据结束=======");
        }else{
            log.info(dto.getContractNo() + "合同状态为非生效状态：{}，跳过修改！",caseContractInfo.getContractStatus());
        }
    }
    public void doCloseContract(LoanActivateReceiveNoticeDTO dto){
        log.info(dto.getContractNo()+"======合同关闭保存业务数据开始=======");
        CaseContractInfo caseContractInfo=caseContractInfoService.getOne(Wrappers.<CaseContractInfo>lambdaQuery().eq(CaseContractInfo::getContractNo,dto.getContractNo()));
        caseContractInfo.setContractStatus(ContractStatusEnum.close);
        caseContractInfo.setEndDate(dto.getCaseDate());
        caseContractInfoService.updateById(caseContractInfo);
        log.info(dto.getContractNo() + "======合同关闭保存业务数据结束=======");
    }
}
